package top.jfunc.common.thread.monitor.bean;

import top.jfunc.common.thread.monitor.ExecutorMonitorData;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class ThreadPoolDetailInfo {
    //线程池所在服务
    private final String service;
    //线程池名称
    private final String poolName;
    //线程池唯一标识
    private final String identifier;
    //当前线程池大小
    private final int poolSize;
    //线程池核心线程数量
    private final int corePoolSize;
    //线程池生命周期中最大线程数量
    private final int largestPoolSize;
    //线程池中允许的最大线程数
    private final int maximumPoolSize;
    //线程池完成的任务数目
    private final long completedTaskCount;
    //线程池中当前活跃个数
    private final int activeCount;
    //线程池当前的任务个数
    private final long taskCount;
    //线程最大空闲时间（毫秒）
    private final long keepAliveTime;
    //是否允许核心线程空闲回收，0和1，数字方便存储
    private final int allowsCoreThreadTimeOut;
    //当前活跃线程的占比
    private final int activePercent;
    //任务队列容量（阻塞队列）
    private final int queueCapacity;
    //当前队列中任务的数量
    private final int queueSize;
    //线程池中任务平均执行时长
    private final long avgExecuteTime;
    //最长执行时间
    private final long maxExecuteTime;
    //最短执行时间
    private final long minExecuteTime;
    //线程池中执行超时次数
    private final long executeTimeoutCount;
    //线程池中执行发生异常次数
    private final long executeExceptionCount;
    //最长等待时间
    private final long maxQueueTime;
    //最短等待时间
    private final long minQueueTime;
    //线程池中排队超时次数
    private final long queueTimeoutCount;
    //拒绝次数
    private final int rejectedCount;
    //线程池启动时间
    private final Date startTime;
    //统计时间
    private final Date createTime;

    public ThreadPoolDetailInfo(String service,
                                String poolName,
                                String identifier,
                                int poolSize,
                                int corePoolSize,
                                int largestPoolSize,
                                int maximumPoolSize,
                                long completedTaskCount,
                                int activeCount,
                                long taskCount,
                                long keepAliveTime,
                                int allowsCoreThreadTimeOut,
                                int activePercent,
                                int queueCapacity,
                                int queueSize,
                                long avgExecuteTime,
                                long maxExecuteTime,
                                long minExecuteTime,
                                long executeTimeoutCount,
                                long executeExceptionCount,
                                long maxQueueTime,
                                long minQueueTime,
                                long queueTimeoutCount,
                                int rejectedCount,
                                Date startTime,
                                Date createTime) {
        this.service = service;
        this.poolName = poolName;
        this.identifier = identifier;
        this.poolSize = poolSize;
        this.corePoolSize = corePoolSize;
        this.largestPoolSize = largestPoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.completedTaskCount = completedTaskCount;
        this.activeCount = activeCount;
        this.taskCount = taskCount;
        this.keepAliveTime = keepAliveTime;
        this.allowsCoreThreadTimeOut = allowsCoreThreadTimeOut;
        this.activePercent = activePercent;
        this.queueCapacity = queueCapacity;
        this.queueSize = queueSize;
        this.avgExecuteTime = avgExecuteTime;
        this.maxExecuteTime = maxExecuteTime;
        this.minExecuteTime = minExecuteTime;
        this.executeTimeoutCount = executeTimeoutCount;
        this.executeExceptionCount = executeExceptionCount;
        this.maxQueueTime = maxQueueTime;
        this.minQueueTime = minQueueTime;
        this.queueTimeoutCount = queueTimeoutCount;
        this.rejectedCount = rejectedCount;
        this.startTime = startTime;
        this.createTime = createTime;
    }

    public static ThreadPoolDetailInfo fromMonitorData(ExecutorMonitorData emd){
        int activePercent = new BigDecimal(emd.getActiveCount()).multiply(new BigDecimal(100))
                .divide(new BigDecimal(emd.getMaximumPoolSize()), 2, RoundingMode.HALF_UP).intValue();

        //总时间/总完成任务数
        long avgExecuteTime = emd.getCompletedTaskCount() == 0L ? 0L : emd.getTotalExecuteTime() / emd.getCompletedTaskCount();

        return new ThreadPoolDetailInfo(emd.getService(), emd.getPoolName(), emd.getIdentifier(),
                emd.getPoolSize(),emd.getCorePoolSize(),emd.getLargestPoolSize(),emd.getMaximumPoolSize(),
                emd.getCompletedTaskCount(),emd.getActiveCount(),emd.getTaskCount(),emd.getKeepAliveTime(TimeUnit.MILLISECONDS),
                emd.allowsCoreThreadTimeOut() ? 1 : 0, activePercent,
                emd.getQueueCapacity(),emd.getQueueSize(),
                avgExecuteTime,emd.getMaxExecuteTime(), emd.getMinExecuteTime(),emd.getExecuteTimeoutCount(),emd.getExecuteExceptionCount(),
                emd.getMaxQueueTime(), emd.getMinQueueTime(), emd.getQueueTimeoutCount(),
                emd.getRejectedCount(),emd.getStartTime(),new Date());
    }

    public String getService() {
        return service;
    }

    public String getPoolName() {
        return poolName;
    }

    public String getIdentifier() {
        return identifier;
    }

    public int getPoolSize() {
        return poolSize;
    }

    public int getCorePoolSize() {
        return corePoolSize;
    }

    public int getLargestPoolSize() {
        return largestPoolSize;
    }

    public int getMaximumPoolSize() {
        return maximumPoolSize;
    }

    public long getCompletedTaskCount() {
        return completedTaskCount;
    }

    public int getActiveCount() {
        return activeCount;
    }

    public long getTaskCount() {
        return taskCount;
    }

    public long getKeepAliveTime() {
        return keepAliveTime;
    }

    public int getAllowsCoreThreadTimeOut() {
        return allowsCoreThreadTimeOut;
    }

    public int getActivePercent() {
        return activePercent;
    }

    public int getQueueCapacity() {
        return queueCapacity;
    }

    public int getQueueSize() {
        return queueSize;
    }

    public long getAvgExecuteTime() {
        return avgExecuteTime;
    }

    public long getMaxExecuteTime() {
        return maxExecuteTime;
    }

    public long getMinExecuteTime() {
        return minExecuteTime;
    }

    public long getExecuteTimeoutCount() {
        return executeTimeoutCount;
    }

    public long getExecuteExceptionCount() {
        return executeExceptionCount;
    }
    public long getMaxQueueTime() {
        return maxQueueTime;
    }

    public long getMinQueueTime() {
        return minQueueTime;
    }

    public long getQueueTimeoutCount() {
        return queueTimeoutCount;
    }

    public int getRejectedCount() {
        return rejectedCount;
    }

    public Date getStartTime() {
        return startTime;
    }

    public Date getCreateTime() {
        return createTime;
    }
}